package com.liveinstars.demo.api.impl;

import com.alibaba.fastjson.JSONObject;
import com.liveinstars.api.config.CommonException;
import com.liveinstars.api.demo.HelloService;
import com.liveinstars.api.demo.model.HelloEnum;
import com.liveinstars.api.demo.model.HelloReq;
import com.liveinstars.api.demo.model.HelloRes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 * 由于EndPoint和ServiceImpl都实现了API的Service接口，为了方便EndPoint使用时注入（省去指定别名），这里指定ServiceImpl为Primary实现
 *
 * 后来发现，若共用API接口，即使指定了Primary也没用，因为Consumer-Application启动时，会根据EnableFeignClients注解的配置去扫API的包，
 * 又因为目前所有微服务的api包名都是com.liveinstars.api开头的，会扫到自己提供的api，因此会发生'primary bean'冲突。（这个场景在Demo里没去模拟，懒得搞了，理解下就行了）
 *
 * 两个解决方案：
 * 1、要么微服务在启动时，更精确的指定EnableFeignClients的扫描范围 —— 这个在开发时会稍微麻烦这么一丢丢，因为若依赖了新的微服务，那么扫描范围就得加。
 * 2、要么微服务EndPoint里注入到Service时（加入Qualifier注解指定别名，Service默认是有别名的）
 *
 * 为了统一配置，用第二种。
 * 尽管官方不建议共用API接口，说是会产生紧耦合。但共用接口带来更好的便捷性和可读性，还是想实践一番，看看会遇到什么问题。
 *
 * Created by guoyanjiang on 2018/11/26.
 */
@Service
public class ProviderServiceImpl implements HelloService {

    Logger logger = LoggerFactory.getLogger(getClass());


    @Override
    public String hello(String strxxx) {
        logger.info("req {}", strxxx);
        return "Hello World";
    }

    @Override
    public HelloRes helloWorld(HelloReq req) {
        logger.info("HelloReq req {}", req.toString());
        return HelloRes.mock();
    }

    @Override
    public HelloRes helloMix(HelloReq req, String strxxx) {
        logger.info("HelloReq req {} strxxx {}", req, strxxx);
        return HelloRes.mock();
    }

    @Override
    public HelloRes helloFastjson(JSONObject req, String str) {
        logger.info("JSONObject req {} str {}", req, str);
        return HelloRes.mock();
    }

    @Override
    public boolean testBoolean() {
        return false;
    }

    @Override
    public void testVoid() {
        logger.info("provider test void, do something... and then return void");
    }

    @Override
    public int testInt(int num) {
        logger.info("req num {}", num);
        num++;
        return num;
    }

    @Override
    public HelloEnum testEnum(HelloEnum helloEnum) {
        logger.info("req enum {}", helloEnum);
        logger.info("req enum's values {} {}", helloEnum.getValue1(), helloEnum.getValue2());
        return HelloEnum.CP_30min;
    }

    @Override
    public void testCallBack(CallBack callBack) {
        logger.info("req a callback, run it");
        callBack.doSomeJob();
        logger.info("call back done");
    }

    @Override
    public void testException() {
        logger.info("test throw a Exception");
        throw new CommonException("hello exception", 400);
    }
}
